package attachment

import (
	"AccessAdmin/internal/dao"
	"AccessAdmin/internal/model"
	"AccessAdmin/internal/service"
	"context"
	"crypto/md5"
	"encoding/hex"
	"fmt"
	"github.com/gogf/gf/v2/errors/gcode"
	"github.com/gogf/gf/v2/errors/gerror"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/net/ghttp"
	"github.com/gogf/gf/v2/os/gfile"
	"github.com/gogf/gf/v2/os/gtime"
	"image"
	_ "image/gif"
	_ "image/jpeg"
	_ "image/png"
	"io"
	"os"
	"path"
	"strings"
)

// 附件资源
type sAttachment struct {
}

func init() {
	service.RegisterAttachment(New())
}

func New() *sAttachment {
	return &sAttachment{}
}

// GetList 获取附件资源列表
func (s *sAttachment) GetList(ctx context.Context, in model.AttachmentGetListInput) (out *model.AttachmentGetListOutput, err error) {
	out = &model.AttachmentGetListOutput{
		Page: in.Page,
		Size: in.Size,
	}
	m := dao.Attachment.Ctx(ctx)
	if in.Name != "" {
		m = m.WhereLike(dao.Attachment.Columns().Name, in.Name)
	}
	if in.Status > 0 {
		m = m.Where(dao.Attachment.Columns().Status, in.Status-1)
	}
	out.Total, err = m.Count()
	if err != nil {
		return out, err
	}
	err = m.Page(in.Page, in.Size).OrderDesc(dao.Attachment.Columns().Id).Scan(&out.List)
	if err != nil {
		return nil, err
	}
	if len(out.List) == 0 {
		return nil, nil
	}
	return out, nil
}

// Create 创建资源
func (s *sAttachment) Create(ctx context.Context, in model.AttachmentCreateInput) (out model.AttachmentCreateOutput, err error) {
	out = model.AttachmentCreateOutput{}
	lastInsertID, err := dao.Attachment.Ctx(ctx).Data(in).InsertAndGetId()
	if err != nil {
		return out, err
	}
	out.AttachmentId = uint(lastInsertID)
	return out, err
}

// Update 修改资源
func (s *sAttachment) Update(ctx context.Context, in model.AttachmentUpdateInput) error {
	attachmentModel, err := service.Attachment().GetDetail(ctx, model.AttachmentGetDetailInput{
		Id: in.Id,
	})
	if err != nil {
		return err
	}
	oldPath := ""
	if attachmentModel.Path != in.Path {
		oldPath = attachmentModel.Path
	}
	_, err = dao.Attachment.Ctx(ctx).Data(in).FieldsEx(dao.Attachment.Columns().Id).Where(dao.Attachment.Columns().Id, in.Id).Update()
	if err != nil {
		return err
	}
	if oldPath != "" {
		s.DeleteFile(ctx, oldPath)
	}
	return nil
}

// Delete 删除资源
func (s *sAttachment) Delete(ctx context.Context, in model.AttachmentGetDetailInput) error {
	attachmentModel, err := service.Attachment().GetDetail(ctx, in)
	if err != nil {
		return err
	}
	_, err = dao.Attachment.Ctx(ctx).Where(dao.Attachment.Columns().Id, in.Id).Unscoped().Delete()
	if err != nil {
		return err
	}
	s.DeleteFile(ctx, attachmentModel.Path)
	return nil
}

// GetDetail 获取分类详情
func (s *sAttachment) GetDetail(ctx context.Context, in model.AttachmentGetDetailInput) (out *model.AttachmentGetDetailOutput, err error) {
	out = &model.AttachmentGetDetailOutput{}
	err = dao.Attachment.Ctx(ctx).As("t1").LeftJoin(dao.AttachmentCate.Table(), "t2", "t1."+dao.Attachment.Columns().CateId+"=t2."+dao.AttachmentCate.Columns().Id).Fields("t1.*,t2."+dao.AttachmentCate.Columns().Title+" as cate_name").Where("t1."+dao.Attachment.Columns().Id, in.Id).Scan(&out)
	if err != nil {
		return nil, err
	}
	return out, nil
}

// DeleteFile 删除多余资源
func (s *sAttachment) DeleteFile(ctx context.Context, Path string) {
	// 删除多余资源
	uploadDir := g.Cfg().MustGet(ctx, "setting.uploadDir").String()
	if !strings.Contains(Path, uploadDir) {
		Path = uploadDir + "/" + Path
	}
	if gfile.IsFile(Path) {
		_ = gfile.Remove(Path)
	}
}

// SetAttachmentContent 获取上传文件信息
func (s *sAttachment) SetAttachmentContent(ctx context.Context, in *model.AttachmentCreateUpdateBase) (*model.AttachmentCreateUpdateBase, error) {
	if in.Path == "" {
		return in, gerror.NewCode(gcode.CodeInvalidParameter, "文件路径不可为空！")
	}
	Path := g.Cfg().MustGet(ctx, "setting.uploadDir").String() + "/" + in.Path
	file, err := os.Open(Path)
	if err != nil {
		fmt.Printf("打开文件失败：%s", err)
		return in, err
	}
	defer file.Close()
	md5h := md5.New()
	_, err = io.Copy(md5h, file)
	if err != nil {
		return in, err
	}
	in.Md5 = hex.EncodeToString(md5h.Sum(nil))
	stat, err := file.Stat()
	if err != nil {
		return in, err
	}
	in.Size = int(stat.Size())
	in.Extension = path.Ext(in.Path)
	nowDate := gtime.Date()
	nowDateArr := strings.Split(nowDate, "-")
	in.Year = nowDateArr[0]
	in.Month = nowDateArr[1]
	in.Day = nowDateArr[2]
	in.UploadIp = ghttp.RequestFromCtx(ctx).GetClientIp()

	contentType, _ := service.Cache().Get(ctx, in.Path)

	fmt.Println(contentType)

	in.SpecificType = contentType.String()

	in.UploadType = "文件"

	if strings.Index(in.SpecificType, "video") != -1 {
		in.UploadType = "视频"
	}

	if strings.Index(in.SpecificType, "image") != -1 {
		in.UploadType = "图片"
	}

	if strings.Index(in.SpecificType, "audio") != -1 {
		in.UploadType = "音频"
	}

	if in.UploadType == "图片" {
		c, _, err := image.DecodeConfig(file)
		if err == nil {
			in.Width = c.Width
			in.Height = c.Height
		}
	}
	return in, nil
}
